package com.ruoyi.system.service.impl;

import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.ttl.threadpool.TtlExecutors;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.ruoyi.common.core.annotation.Excel;
import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.domain.vo.BasePositionMsgVO;
import com.ruoyi.system.domain.vo.BasePositionResponseVO;
import com.ruoyi.system.domain.vo.BaseSubstitutionRequestVO;
import com.ruoyi.system.mapper.BaseBasketballPlayerMapper;
import com.ruoyi.system.mapper.BaseTournamentMapper;
import com.ruoyi.system.service.IBaseAttendanceLogService;
import com.ruoyi.system.service.IBaseContestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.system.mapper.BasePlayerPositionLogMapper;
import com.ruoyi.system.service.IBasePlayerPositionLogService;

import javax.annotation.Resource;

/**
 * 球员阵位记录Service业务层处理
 * 
 * @author wangbj
 * @date 2024-04-16
 */
@Service
public class BasePlayerPositionLogServiceImpl extends ServiceImpl<BasePlayerPositionLogMapper, BasePlayerPositionLog> implements IBasePlayerPositionLogService
{
    @Resource
    private BasePlayerPositionLogMapper basePlayerPositionLogMapper;

    @Resource
    private BaseTournamentMapper baseTournamentMapper;

    @Resource
    private BaseBasketballPlayerMapper baseBasketballPlayerMapper;

    @Resource
    LoginUserSetUtil loginUserSetUtil;

    @Resource
    private IBaseAttendanceLogService iBaseAttendanceLogService;

    @Resource
    private IBaseContestService iBaseContestService;

    private static ExecutorService executorService = Executors.newFixedThreadPool(5);


    /**
     * 查询球员阵位记录
     * 
     * @param id 球员阵位记录主键
     * @return 球员阵位记录
     */
    @Override
    public BasePlayerPositionLog selectBasePlayerPositionLogById(Long id)
    {
        return basePlayerPositionLogMapper.selectBasePlayerPositionLogById(id);
    }

    /**
     * 查询球员阵位记录列表
     * 
     * @param basePlayerPositionLog 球员阵位记录
     * @return 球员阵位记录
     */
    @Override
    public List<BasePlayerPositionLog> selectBasePlayerPositionLogList(BasePlayerPositionLog basePlayerPositionLog)
    {
        return basePlayerPositionLogMapper.selectBasePlayerPositionLogList(basePlayerPositionLog);
    }

    /**
     * 新增球员阵位记录
     * 
     * @param basePlayerPositionLog 球员阵位记录
     * @return 结果
     */
    @Override
    public int insertBasePlayerPositionLog(BasePlayerPositionLog basePlayerPositionLog)
    {
        basePlayerPositionLog.setCreateTime(DateUtils.getNowDate());
        return basePlayerPositionLogMapper.insertBasePlayerPositionLog(basePlayerPositionLog);
    }

    /**
     * 修改球员阵位记录
     * 
     * @param basePlayerPositionLog 球员阵位记录
     * @return 结果
     */
    @Override
    public int updateBasePlayerPositionLog(BasePlayerPositionLog basePlayerPositionLog)
    {
        basePlayerPositionLog.setUpdateTime(DateUtils.getNowDate());
        return basePlayerPositionLogMapper.updateBasePlayerPositionLog(basePlayerPositionLog);
    }

    /**
     * 批量删除球员阵位记录
     * 
     * @param ids 需要删除的球员阵位记录主键
     * @return 结果
     */
    @Override
    public int deleteBasePlayerPositionLogByIds(Long[] ids)
    {
        return basePlayerPositionLogMapper.deleteBasePlayerPositionLogByIds(ids);
    }

    /**
     * 删除球员阵位记录信息
     * 
     * @param id 球员阵位记录主键
     * @return 结果
     */
    @Override
    public int deleteBasePlayerPositionLogById(Long id)
    {
        return basePlayerPositionLogMapper.deleteBasePlayerPositionLogById(id);
    }

    /**
     * 球员阵位
     *
     * @param tournamentId
     * @return
     */
    @Override
    public BasePositionResponseVO createPosition(Long tournamentId) {

        BaseTournament tournament = baseTournamentMapper.selectBaseTournamentById(tournamentId);

        if (ObjectUtil.isNull(tournament)){
            throw new RuntimeException("比赛不存在");
        }
        //删除原来的
        baseMapper.deletePositionByToumentId(tournamentId);

        CompletionService<String> completionService = new ExecutorCompletionService<>(executorService);

        //构建返回
        BasePositionResponseVO basePositionResponseVO = new BasePositionResponseVO();
        //多线程处理
        completionService.submit(() -> {
            basePositionResponseVO.setOneTeamList(this.autoCreate(tournamentId, tournament, 1));
            return "队伍1完成";
        });

        completionService.submit(() -> {
            basePositionResponseVO.setTwoTeamList(this.autoCreate(tournamentId, tournament, 2));
            return "队伍2完成";
        });

        //处理结果等待返回
        for (int i = 1; i <=2 ; i++) {
            try {
                Future<String> future = completionService.take(); // 等待下一个完成的任务
                String result = future.get(); // 获取任务的结果
                System.out.println("任务执行结束，结果是：" + result);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        return basePositionResponseVO;
    }


    /**
     * 创建阵位 执行代码
     * @param tournamentId
     * @param tournament
     * @param teamType 1 代表第一个队伍 2 代表第二个队伍
     * @return
     */
    private List<BasePositionMsgVO> autoCreate(Long tournamentId, BaseTournament tournament,int teamType) {

        Long id = teamType == 1 ? tournament.getTeamOneId():tournament.getTeamTwoId();
        //拿到第一个队伍的球员
        List<BaseBasketballPlayer> oneList = baseBasketballPlayerMapper.getPlayerByTimeId(id,tournamentId);

        if (CollectionUtil.isEmpty(oneList)){
            throw new RuntimeException("当前队伍不存在");
        }
        //处理第队伍一个阵位信息
        AtomicInteger temp = new AtomicInteger(1); //阵位下标
        List<BasePlayerPositionLog> list = new ArrayList<>();
        oneList.forEach(item -> {
            BasePlayerPositionLog basePlayerPositionLog = new BasePlayerPositionLog()
                    .setBasketballPlayerId(item.getId())
                    .setTournamentId(tournamentId)
                    .setBasketballTeamId(id)
                    .setSeasonId(tournament.getSeasonId())
                    .setOrganizationId(tournament.getOrganizationId())
                    .setContestId(tournament.getContestId())
                    .setType(item.getIsUp() == 1 ? 0 : 1)
                    .setSort(temp.get())
                    .setIsComeOn(item.getIsUp() == 1 ? 0 : 1)
                    .setSubsection(1L);
            temp.getAndIncrement();
            //优化点
//            loginUserSetUtil.populateFields(basePlayerPositionLog,1);
            list.add(basePlayerPositionLog);
        });
        baseMapper.insertBatch(list);
        return baseMapper.getCreatePositionLog(tournament.getId(),tournament.getContestId(),id);

    }

    /**
     * 调换球员
     *
     * @param requestVO
     * @return
     */
    @Override
    public List<BasePositionMsgVO> substitution(BaseSubstitutionRequestVO requestVO) {
        if (ObjectUtil.isNull(requestVO)){
            throw new RuntimeException("参数不能为空");
        }
        if (ObjectUtil.isNull(requestVO.getTournamentId())){
            throw new RuntimeException("比赛id不能为空");
        }
        if (ObjectUtil.isNull(requestVO.getTeamId())){
            throw new RuntimeException("队伍id不能为空");
        }
        if (ObjectUtil.isNull(requestVO.getPlayerOneId())){
            throw new RuntimeException("调换球员id不能为空");
        }
        if (ObjectUtil.isNull(requestVO.getPlayerTwoId())){
            throw new RuntimeException("被调换球员id不能为空");
        }

        List<BasePlayerPositionLog> list = baseMapper.selectByPlayer(requestVO);
        if (CollectionUtil.isEmpty(list) || list.size()!=2){
            throw new RuntimeException("球员不存在");
        }
        BaseBasketballPlayer baseBasketballPlayer = baseBasketballPlayerMapper.selectById(requestVO.getPlayerOneId());
        BaseAttendanceLog build = BaseAttendanceLog.builder().basketballTeamId(requestVO.getTeamId())
                .tournamentId(requestVO.getTournamentId())
                .playerNumber(baseBasketballPlayer.getPlayerNumber())
                .basketballPlayerId(requestVO.getPlayerOneId())
                .organizationId(SecurityUtils.getOrganizationId())
                .contestId(SecurityUtils.getContestId())
                .isAttendance(1L)
                .build();
        List<BaseAttendanceLog> listLog = new ArrayList<>();
        listLog.add(build);
        iBaseAttendanceLogService.saveList(listLog,requestVO.getTournamentId(),requestVO.getTeamId());

        //list只会存在两条数据
        for (int i = 0; i < list.size(); i++) {
            LambdaUpdateWrapper<BasePlayerPositionLog> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(BasePlayerPositionLog::getId,list.get(i).getId());
            if (i == 0){
                updateWrapper.set(BasePlayerPositionLog::getSort,list.get(1).getSort());
            }
            if (i == 1){
                updateWrapper.set(BasePlayerPositionLog::getSort,list.get(0).getSort());
            }
            updateWrapper.set(BasePlayerPositionLog::getUpdateTime,new Date());
            baseMapper.update(null,updateWrapper);
        }

        return baseMapper.getCreatePositionLog(list.get(0).getTournamentId(),list.get(0).getContestId(),list.get(0).getBasketballTeamId());
    }

    @Override
    public BasePositionResponseVO substitutionPlayer(BaseSubstitutionRequestVO requestVO) {
        if (ObjectUtil.isNull(requestVO)){
            throw new RuntimeException("参数不能为空");
        }
        if (ObjectUtil.isNull(requestVO.getTournamentId())){
            throw new RuntimeException("比赛id不能为空");
        }
        BaseTournament baseTournament = baseTournamentMapper.selectById(requestVO.getTournamentId());
        if(Objects.isNull(baseTournament)){
            throw new RuntimeException("未找到当前赛事");
        }
        BaseContest byId = iBaseContestService.getById(SecurityUtils.getContestId());
        if (Objects.isNull(byId)){
            throw new RuntimeException("未找到当前联赛");
        }
        BasePositionResponseVO basePositionResponseVO = new BasePositionResponseVO();

        basePositionResponseVO.setOneTeamList(buildPoistionMsg(requestVO,byId.getScoringWay(),baseTournament.getTeamOneId())) ;
        basePositionResponseVO.setTwoTeamList(buildPoistionMsg(requestVO,byId.getScoringWay(),baseTournament.getTeamTwoId())) ;
        return basePositionResponseVO;
    }

    private List<BasePositionMsgVO> buildPoistionMsg(BaseSubstitutionRequestVO requestVO,Long way,Long teamId) {
        List<BasePositionMsgVO> createPositionLog = baseMapper.getCreatePositionLog(requestVO.getTournamentId(), SecurityUtils.getContestId(), teamId);
        if (CollUtil.isEmpty(createPositionLog)){
            return createPositionLog;
        }
        Integer num = Objects.equals(way,1L) ? 3 : 5;

        if (createPositionLog.size() < (num * 2)){
            throw new RuntimeException("替补席到场人员不足"+num+"人,请您拖拽换人上场");
        }
        List<BasePlayerPositionLog> voList = new ArrayList<>();
        List<BaseAttendanceLog> voListLog = new ArrayList<>();
        for (int i = 0; i < num ; i++) {
            BasePositionMsgVO basePositionMsgVO = createPositionLog.get(i);
            basePositionMsgVO.setSort(num+i+1);
            voList.add(basePositionMsgVO);
        }
        //上场
        for (int i = 0; i < num ; i++) {
            BasePositionMsgVO basePositionMsgVO = createPositionLog.get(i+num);
            basePositionMsgVO.setSort(i+1);
            voList.add(basePositionMsgVO);

            BaseAttendanceLog build = BaseAttendanceLog.builder()
                    .basketballTeamId(teamId)
                    .tournamentId(requestVO.getTournamentId())
                    .playerNumber(basePositionMsgVO.getPlayerNumber())
                    .basketballPlayerId(basePositionMsgVO.getBasketballPlayerId())
                    .organizationId(SecurityUtils.getOrganizationId())
                    .contestId(SecurityUtils.getContestId())
                    .isAttendance(1L)
                    .build();
            voListLog.add(build);
        }
        iBaseAttendanceLogService.saveList(voListLog,requestVO.getTournamentId(),teamId);
        this.updateBatchById(voList);
        createPositionLog = createPositionLog.stream()
                .sorted(Comparator.comparing(BasePositionMsgVO::getSort))
                .collect(Collectors.toList());
        return createPositionLog;
    }

}
